use std::cell::RefCell;

/**
 * 二进制数据读取工具
 */
pub struct ByteDataReader {
    pub data: Vec<u8>,
    pub index: usize,
}

impl ByteDataReader {
    pub const fn new(data: Vec<u8>) -> ByteDataReader {
        return ByteDataReader {
            data,
            index: 0,
        };
    }

    pub fn read_mutf8_str(&mut self, len: u16) -> String {
        let mut result = String::new();

        let mut count = 0;
        while count < len {
            let c = self.read_u8() & 0xff;
            let tag = c >> 4;
            match tag {
                0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 => {
                    count = count + 1;
                    result.push(char::from(c));
                }
                12 | 13 => {
                    count = count + 2;
                    let c1 = c as u32;
                    let c2 = self.read_u8() as u32;
                    let cv = ((c1 & 0x1F) << 6) | (c2 & 0x3F);
                    result.push(char::from_u32(cv).unwrap());
                }
                14 => {
                    count = count + 3;
                    let c1 = c as u32;
                    let c2 = self.read_u8() as u32;
                    let c3 = self.read_u8() as u32;
                    let cv = ((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | ((c3 & 0x3F) << 0);
                    result.push(char::from_u32(cv).unwrap());
                }
                _ => {
                    println!("mutf8解码失败");
                }
            }
        }

        return result;
    }

    pub fn read_u8(&mut self) -> u8 {
        let temp_index = self.index;
        self.index = self.index + 1;
        return self.data[temp_index];
    }

    pub fn read_bytes(&mut self, len: u32) -> RefCell<Vec<u8>> {
        let mut result = Vec::new();
        for _i in 0..len {
            result.push(self.read_u8());
        }
        return RefCell::new(result);
    }

    pub fn read_u16(&mut self) -> u16 {
        return u16::from_be_bytes([self.read_u8(), self.read_u8()]);
    }

    pub fn read_u32(&mut self) -> u32 {
        return u32::from_be_bytes([self.read_u8(), self.read_u8(), self.read_u8(), self.read_u8()]);
    }

    pub fn read_i16(&mut self) -> i16 {
        return i16::from_be_bytes([self.read_u8(), self.read_u8()]);
    }

    pub fn read_i32(&mut self) -> i32 {
        return i32::from_be_bytes([self.read_u8(), self.read_u8(), self.read_u8(), self.read_u8()]);
    }

    pub fn read_i64(&mut self) -> i64 {
        return i64::from_be_bytes([self.read_u8(), self.read_u8(), self.read_u8(), self.read_u8(), self.read_u8(), self.read_u8(), self.read_u8(), self.read_u8()]);
    }


    pub fn read_f32(&mut self) -> f32 {
        return f32::from_be_bytes([self.read_u8(), self.read_u8(), self.read_u8(), self.read_u8()]);
    }

    pub fn read_f64(&mut self) -> f64 {
        return f64::from_be_bytes([self.read_u8(), self.read_u8(), self.read_u8(), self.read_u8(), self.read_u8(), self.read_u8(), self.read_u8(), self.read_u8()]);
    }
}